package com.amumu.drama.common.modules.member.service.impl;

import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.amumu.drama.common.base.api.CommonResult;
import com.amumu.drama.common.config.WXProperties;
import com.amumu.drama.common.modules.captcha.service.CaptchaService;
import com.amumu.drama.common.modules.idverify.service.IdVerifyService;
import com.amumu.drama.common.modules.member.cache.MemberCache;
import com.amumu.drama.common.modules.member.service.UmsMemberCacheService;
import com.amumu.drama.common.modules.member.service.UmsMemberService;
import com.amumu.drama.common.modules.service.impl.sms.model.SmsResponse;
import com.amumu.drama.common.utils.HttpUtils;
import com.amumu.drama.mapper.UmsMemberMapper;
import com.amumu.drama.model.UmsMember;
import com.amumu.drama.model.UmsMemberExample;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;

/**
 * 会员管理Service实现类
 * Created by macro on 2018/8/3.
 */
@Service
public class UmsMemberServiceImpl extends ServiceImpl<UmsMemberMapper, UmsMember> implements UmsMemberService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsMemberServiceImpl.class);
    private static final String PHONE_NUMBER_REGEX = "^1[3-9]\\d{9}$";
    @Autowired
    private UmsMemberMapper memberMapper;
    @Autowired
    private WXProperties wxProperties;

    @Autowired
    private UmsMemberCacheService memberCacheService;

    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private IdVerifyService idVerifyService;

    @Override
    public UmsMember getByUsername(String username) {
        UmsMember member = memberCacheService.getMember(username);
        if (member != null) {
            return member;
        }
        UmsMemberExample example = new UmsMemberExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<UmsMember> memberList = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(memberList)) {
            member = memberList.get(0);
            memberCacheService.setMember(member);
            return member;
        }
        return null;
    }

    @Override
    public UmsMember getByPhoneNum(String phoneNum) {
        UmsMember member = memberCacheService.getMember(phoneNum);
        if (member != null) {
            return member;
        }
        UmsMemberExample example = new UmsMemberExample();
        example.createCriteria().andPhoneEqualTo(phoneNum);
        List<UmsMember> memberList = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(memberList)) {
            member = memberList.get(0);
            memberCacheService.setMember(member);
            return member;
        }
        return null;
    }

    @Override
    public UmsMember getById(Long id) {
        return memberMapper.selectByPrimaryKey(id);
    }


    @Override
    public void updateIntegration(Long id, BigDecimal integration) {
        UmsMember record = new UmsMember();
        record.setId(id);
        record.setIntegration(integration == null ? new BigDecimal("0") : integration);
        memberMapper.updateByPrimaryKeySelective(record);
        MemberCache.INSTANCE.invalidateById(id);
    }


    @Override
    public CommonResult<Boolean> sendSmsCaptcha(String phoneNum) {
        try {
            Pattern pattern = Pattern.compile(PHONE_NUMBER_REGEX);
            if (!pattern.matcher(phoneNum).matches()) {
                throw new RuntimeException("手机号码非法");
            }

            SmsResponse smsResponse = captchaService.sendSmsCaptcha(phoneNum);
            if (!smsResponse.getResult()) {
                return CommonResult.failed("测试环境未开放注册登陆".equals(smsResponse.getMessage()) ? smsResponse.getMessage() : "发送验证码失败，请稍后重试");
            }
            return CommonResult.success();
        } catch (Exception e) {
            LOGGER.warn("{}发送验证码失败:{}", phoneNum, e.getMessage(), e);
            return CommonResult.failed("发送验证码失败，请稍后重试");
        }
    }


    @Override
    public CommonResult<String> verifyIdCard(Long memberId, String realName, String idCard) {
        try {
            UmsMember member = MemberCache.INSTANCE.getFromCache(memberId);
            if (member == null) {
                return CommonResult.failed("用户不存在");
            }
            if (checkRealName(member)) {
                return CommonResult.success("用户已认证");
            }
            if (IdcardUtil.getAgeByIdCard(idCard) < 18) {
                return CommonResult.failed("不满18岁，无法认证!");
            }
            UmsMember updateMember = new UmsMember();
            updateMember.setRealName(realName);
            updateMember.setIdCard(idCard);
            updateMember.setId(memberId);
            if (idVerifyService.verifyIdCard(memberId, realName, idCard)) {
                memberMapper.updateById(updateMember);
                memberCacheService.setMember(member);
                MemberCache.INSTANCE.invalidateById(memberId);
                return CommonResult.success("实名认证成功");
            }
            LOGGER.warn("{}-{}-{}-实名认证失败", member, realName, idCard);
            return CommonResult.failed("实名认证失败，请稍后重试");
        } catch (Exception e) {
            LOGGER.warn("{}-实名认证异常:{}", memberId, e.getMessage());
            return CommonResult.failed("实名认证失败，请稍后重试");
        }
    }

    @Override
    public boolean checkRealName(UmsMember member) {
        if (member != null) {
            return !StrUtil.hasBlank(member.getRealName(), member.getIdCard());

        }
        return false;
    }

    @Override
    public CommonResult<String> getOpenId(UmsMember member, String code) {
        // 拼接请求地址
        String requestUrl = wxProperties.getOpenUrl() + "?appid=" + wxProperties.getAppId()
                + "&secret=" + wxProperties.getAppSecret()
                + "&code=" + code
                + "&grant_type=authorization_code";
        try {
            HttpResponse response = HttpUtils.doGet(requestUrl);
            LOGGER.info("{}-{}getOpenId:{}", member.getId(), code, JSONUtil.toJsonStr(response));
            Map responseMap = JSONUtil.toBean(JSONUtil.toJsonStr(response.getEntity()), Map.class);
            if (!"200".equals(responseMap.get("code").toString()) || !"success".equals(responseMap.get("message"))) {
                return CommonResult.failed();
            }
            String openId = Optional.ofNullable(responseMap.get("openid")).map(String::valueOf).orElse(null);
            return CommonResult.success(openId);
        } catch (Exception e) {
            LOGGER.warn("获取OpenId异常:{}", e.getMessage());
            return CommonResult.failed();
        }
    }


}
